#include "server.h"

#define READONLY "ro"

Server::Server()
{
    connect(qApp, &QApplication::aboutToQuit, this, [&]{
        isExit = true;
    });
}

void Server::run()
{
    while (!isExit)
    {
        CheckSD2State();
        sleep(1);
    }
}

bool Server::isMountPoint(const char *mountPath)
{
    int ret = 0;
    char line[256];
    FILE *fMounts = fopen("/proc/self/mounts", "r");

    if (fMounts)
    {
        while (fgets(line, sizeof(line), fMounts))
        {
            if (strstr(line, mountPath))
            {
                ret = 1;
                break;
            }
        }
        fclose(fMounts);
    }

    return ret;
}

bool Server::isSDCardMount()
{
    return isMountPoint(PATH);
}

void Server::CheckSD2State()
{
    if (isSDCardMount())
    {
        if (!isSD2In)
        {
            isSD2In = true;
            log_debug() << "SDCRAD IN";

            isSD2CheckCnt = 0;

            QProcess *p = new QProcess();
            QObject::connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), p, &QProcess::deleteLater);
            p->startDetached("mount -t vfat -o rw,noatime,uid=1000,gid=1000,fmask=0133,dmask=0022,codepage=936,iocharset=cp936,shortname=mixed,errors=remount-ro /dev/mmcblk0p1 /mnt/sdcard");
            p->waitForStarted();
            p->waitForFinished();

            checkRW();
        }
        else if (isSD2CheckCnt < 2)
        {
            isSD2CheckCnt++;
        }
        else if (isSD2CheckCnt == 2)
        {
            log_debug() << "need to scan";
            isSD2CheckCnt++;
        }
    }
    else
    {
        if (isSD2In)
        {
            isSD2In = false;
            log_debug() << "SDCRAD OUT";

            isSD2CheckCnt = 0;

            QProcess *p = new QProcess();
            p->startDetached("umount /mnt/sdcard");
            p->waitForStarted();
            QObject::connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), p, &QProcess::deleteLater);
        }
        else if (isSD2CheckCnt < 2)
        {
            isSD2CheckCnt++;
        }
        else if (isSD2CheckCnt == 2)
        {
            log_debug() << "need to scan";
            isSD2CheckCnt++;
        }
    }
}

void Server::checkRW()
{
    QProcess p;
    p.start("cat /proc/mounts");
    p.waitForFinished();
    QString data = p.readAll();
    log_debug() << "read : " << data;
    if(data.isEmpty())
    {
        log_debug() << "sd card mount fail";
        QProcess *p = new QProcess();
        QObject::connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), p, &QProcess::deleteLater);
        p->startDetached("mount /dev/mmcblk0p1 /mnt/sdcard");
        p->waitForStarted();
    }
    else
    {
        QString buf = data.mid(data.indexOf("/dev/mmcblk0p1"));
        if(buf.isEmpty())
        {
            log_debug() << "sd card mount fail";
            QProcess *p = new QProcess();
            QObject::connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), p, &QProcess::deleteLater);
            p->startDetached("mount /dev/mmcblk0p1 /mnt/sdcard");
            p->waitForStarted();
        }
        else
        {
            QStringList list = buf.split("\n");
            if(list.size() > 0)
            {
                data = list.at(0);
                log_debug() << data;
                QStringList list1 = data.split(" ");
                if(list1.size() >= 4)
                {
                    data = list1.at(3);
                    log_debug() << data;
                    if(data.startsWith(READONLY))
                    {
                        log_debug() << "remount";
                        QProcess *p = new QProcess();
                        QObject::connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), p, &QProcess::deleteLater);
                        p->startDetached("mount /dev/mmcblk0p1 /mnt/sdcard");
                        p->waitForStarted();
                    }
                    else
                        log_debug() << "mount ok";
                }
            }
        }
    }
}

